package com.forum.module.blog.service.comment;

import com.alibaba.nacos.shaded.com.google.common.annotations.VisibleForTesting;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.forum.framework.common.exception.util.ServiceExceptionUtils;
import com.forum.framework.common.pojo.PageResult;
import com.forum.framework.common.util.object.BeanUtils;
import com.forum.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.forum.framework.mybatis.core.query.QueryWrapperX;
import com.forum.framework.security.core.LoginUser;
import com.forum.framework.security.core.util.SecurityUtils;
import com.forum.module.blog.controller.comment.vo.CommentPageReqVO;
import com.forum.module.blog.controller.comment.vo.CommentSavaReqVO;
import com.forum.module.blog.dal.dataobject.article.ArticleDO;
import com.forum.module.blog.dal.dataobject.category.CategoryDO;
import com.forum.module.blog.dal.dataobject.comment.CommentDO;
import com.forum.module.blog.dal.mysql.article.ArticleMapper;
import com.forum.module.blog.dal.mysql.comment.CommentMapper;
import com.forum.module.blog.service.notification.NotificationService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

import static com.forum.module.system.enums.ErrorCodeConstants.CATEGORY_NOT_EXISTS;
import static com.forum.module.system.enums.ErrorCodeConstants.COMMENT_NOT_EXISTS;

/**
 * 功能:
 * 作者:ouyzh
 * 日期:2025/3/2 18:28
 */
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, CommentDO> implements CommentService {
    private final CommentMapper commentMapper;

    private final ArticleMapper articleMapper;

    private final NotificationService notificationService;

    public CommentServiceImpl(CommentMapper commentMapper,
                              ArticleMapper articleMapper,
                              NotificationService notificationService) {
        this.commentMapper = commentMapper;
        this.articleMapper = articleMapper;
        this.notificationService = notificationService;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createComment(CommentSavaReqVO reqVO) {
        Long loginUserId = SecurityUtils.getLoginUserId();
        CommentDO commentDO = BeanUtils.toBean(reqVO, CommentDO.class);
        commentDO.setStatus(0);
        commentDO.setUserId(loginUserId);
        commentDO.setParentId(reqVO.getParentId() != null ? reqVO.getParentId() : 0L);

        articleMapper.update(null,
                new LambdaUpdateWrapper<ArticleDO>()
                        .eq(ArticleDO::getId, reqVO.getArticleId())
                        .setSql("comments = comments + 1"));

        ArticleDO articleDO = articleMapper.selectById(reqVO.getArticleId());
        LoginUser loginUser = SecurityUtils.getLoginUser();
        assert loginUser != null;
        String message = "用户:" +
                loginUser.getInfo().get("nickname") +
                "，评论了你的文章，或是回复了你的评论！";
        notificationService.sendMessage(articleDO.getUserId(), 1, message);

        commentMapper.insert(commentDO);
        return commentDO.getId();
    }

    @Override
    public void updateComment(CommentSavaReqVO reqVO) {
        CommentDO updateObj = BeanUtils.toBean(reqVO, CommentDO.class);
        commentMapper.updateById(updateObj);
    }

    @Override
    public void deleteById(Long id) {
        // 1. 校验评论存在
        validateCommentExists(id);

        commentMapper.deleteById(id);
    }

    @Override
    public PageResult<CommentDO> getCommentPage(CommentPageReqVO pageReqVO) {
        return commentMapper.selectPage(pageReqVO);
    }

    @Override
    public List<CommentDO> getChildComments(Long id) {
        return commentMapper.selectList(new QueryWrapperX<CommentDO>()
                .eq("parent_id", id));
    }


    @VisibleForTesting
    CommentDO validateCommentExists(Long id) {
        if (id == null) {
            return null;
        }
        CommentDO commentDO = commentMapper.selectById(id);
        if (commentDO == null) {
            throw ServiceExceptionUtils.exception(COMMENT_NOT_EXISTS);
        }
        return commentDO;
    }
}
